<?php

namespace App\Jobs;

use Illuminate\Bus\Queueable;
use Illuminate\Contracts\Queue\ShouldQueue;
use Illuminate\Foundation\Bus\Dispatchable;
use Illuminate\Queue\InteractsWithQueue;
use Illuminate\Queue\SerializesModels;
use Illuminate\Support\Facades\Log;
use PHPUnit\Exception;
use siafei\Reporting\ReportFacade;
use Throwable;

class ReportErrJob implements ShouldQueue
{

    use Dispatchable, InteractsWithQueue, Queueable, SerializesModels;

    private $err;

    public function __construct(Throwable $exception)
    {

        $this->err = $this->getErrorMessange($exception);
    }


    public function handle(): void
    {
        try {
            ReportFacade::report($this->err);
        } catch (Exception $exception) {
            Log::error("上报错误到钉钉失败:" . $exception->getMessage());
        }
    }



    private function getErrorMessange(Exception $exception)
    {
        $projectEnv = $this->getProjectEnv();
        $requestTime = date('Y-m-d H:i:s', $this->getServerEnv('REQUEST_TIME'));
        $requestUrl = $this->getServerEnv('REQUEST_URI');
        $requestParams = [];
        if (in_array($this->getServerEnv('REQUEST_METHOD'), ['GET', 'POST', 'PUT', 'DELETE'])) {
            $requestParams = $_REQUEST;
        }
        $excptMsg = $exception->getMessage();

        $info = [
            '系统名称' => getenv('APP_NAME'),
            '异常类' => [
                '文件' => $exception->getFile(),
                '行数' => $exception->getLine(),
                '异常类' => get_class($exception),
                '异常code' => $exception->getCode(),
                '异常消息' => $excptMsg,
            ],
            '请求' => [
                '请求时间' => $requestTime,
                '请求方法' => $this->getServerEnv('REQUEST_METHOD'),
                '请求地址' => $requestUrl,
                '请求参数' => $requestParams,
            ],
            '环境' => [
                '项目环境' => $projectEnv,
                '站点名称' => $this->getServerEnv('SERVER_NAME'),
                '服务器IP' => $this->getServerEnv('SERVER_ADDR'),
                '变量APP_ENV' => $this->getServerEnv('APP_ENV'),
                '变量SITE_LOG_DIR' => $this->getServerEnv('LOG_DIR'),
            ],
        ];

        return json_encode($info, JSON_UNESCAPED_UNICODE | JSON_PRETTY_PRINT | JSON_UNESCAPED_SLASHES);
    }


    /**
     * 安全获取环境变量
     *
     * @param $attr
     *
     * @return mixed|null
     */
    public function getServerEnv($attr)
    {
        return $_SERVER[$attr] ?? null;
    }

    /**
     * 获取客户端ip
     *
     * @return mixed|null
     */
    final public function getClientIP()
    {
        $ip = null;
        !$ip && !empty($_SERVER["REMOTE_ADDR"]) && $ip = $_SERVER["REMOTE_ADDR"];
        !$ip && !empty($_SERVER['HTTP_CLIENT_IP']) && $ip = $_SERVER['HTTP_CLIENT_IP'];
        !$ip && !empty($_SERVER['HTTP_X_FORWARD_FOR']) && $ip = $_SERVER['HTTP_X_FORWARD_FOR'];
        return $ip;
    }

    /**
     * 是否是生产环境
     *
     * @return string
     */
    public function getProjectEnv()
    {
        return getenv('APP_ENV') ?? '未知环境';
    }
}
